<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>完整生命周期</title>
    <script type="text/javascript" src="../js/vue.js"></script>
    <script type="text/javascript">
      Vue.config.productionTip = false;
    </script>
  </head>

  <body>
    <div id="root">
      <h2>当前的值是: {{n}}</h2>
      <button @click="add">点我n+1</button>
      <button @click="bye">点我销毁VM</button>
      <h2 v-text="n"></h2>
    </div>
  </body>

  <script type="text/javascript">
    new Vue({
      //如果不指定容器，只会执行 beforeCreate 和 created 两个钩子
      el: "#root",

      //或使用模板语法，但是————1:不可以和el同时使用  2:只能包含一个根元素，会直接替换上面的模板
      // template: `
      // <div>
      //   <h2>当前的值是: {{n}}</h2>
      //   <button @click="add">点我n+1</button>
      // </div>
      // `,
      data: {
        n: 1,
      },
      methods: {
        add() {
          console.log("触发n的增加方法");
          this.n++;
        },
        bye() {
          console.log("触发VM的销毁方法");
          //调用VM销毁方法，注意VM会被销毁，但是页面内容还是会存在的，只是按钮什么的无效了
          //并清理它与其他实例的连接（组件）
          this.$destroy();
        },
      },
      watch: {
        n() {
          //调用销毁后，无法使用
          console.log("监视属性察觉到n变化了");
        },
      },

      //1：【创建前置】钩子函数，特点是无法通过vm获取到data和methods中的属性及方法
      beforeCreate() {
        console.log("调用创建前置,beforeCreate。生命周期中的this都是VM");
        console.log(this);
        //添加断点，执行代码停到这里    可看到VM中的属性和方法还不存在，其他数据也大多为空或false
        //debugger;
      },

      //2：【创建完毕】钩子函数，已执行完数据监测和数据代理，可访问data和methods内容
      created() {
        console.log("调用创建完毕,created");
        console.log(this);
        //debugger;
      },

      //———————继续往下走，会先生成【虚拟】DOM

      //3：【挂载前置】钩子函数，此时还没放到页面上
      beforeMount() {
        console.log("调用挂载前置,beforeMount");
        console.log(this);
        //所有对DOM的操作，最终都不奏效！！！
        document.querySelector("h2").innerText = "哈哈";
        //debugger;
      },

      //———————随后，Vue会虚拟DOM转为真实DOM插入页面，原始是替换el，并且Vue会在【$el】下保存一份原始虚拟DOM

      //4：【挂载完毕】钩子函数，对DOM的操作均有效，尽量避免
      mounted() {
        console.log("调用挂载完毕,mounted");
        console.log(this);
        //至此初始化过程结束，一般在该节点处理：定时器、网络请求、订阅消息、绑定事件等初始化操作
        //document.querySelector("h2").innerText = "123";
        //debugger;
      },

      //5：【更新前置】钩子函数，数据发生更新时触发
      beforeUpdate() {
        console.log("调用更新前置,beforeUpdate");
        console.log(this);
        //数据是更新后的新数据，但页面是旧的。尚未同步
        //debugger;
      },

      //———————紧接着，会根据新数据生成新的虚拟DOM，与旧的虚拟DOM进行比较，最后更新到页面
      //即完成了Model -> View的更新

      //6：【更新完毕】钩子函数，数据和页面完成更新数据同步
      updated() {
        console.log("调用更新完毕,updated");
        console.log(this);
        //debugger;
      },

      //7：【销毁前置】钩子函数，销毁VM时触发
      beforeDestroy() {
        console.log("调用销毁前置,beforeDestroy");
        //此时vm中的属性还可以正常使用，马上要执行销毁过程
        //一般在此阶段：关闭定时器、取消订阅消息、解绑自定义事件等收尾操作
        console.log(this);
        //但是，这里调用的方法不会触发更新！！！原理是不触发beforeUpdate和updated更新函数
        this.add();
        //debugger;
      },

      //8：【销毁完毕】钩子函数，VM销毁完毕，页面不再由Vue管理
      destroyed() {
        console.log("调用销毁完毕,destroyed");
        console.log(this);
        //debugger;
      },

      //结束
    });
  </script>
</html>
